package com.hongfeng.support.service.common.impl;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;

import com.hongfeng.support.common.Page;
import com.hongfeng.support.dao.common.GenericDao;
import com.hongfeng.support.item.OrderItem;
import com.hongfeng.support.item.ParmItem;
import com.hongfeng.support.item.QueryItem;
import com.hongfeng.support.service.common.GenericService;
import com.hongfeng.support.util.SpringContextHelper;

public class GenericServiceImpl<T, PK extends Serializable> implements
		GenericService<T, PK> {

	private GenericDao<T, PK> genericDao;

	@SuppressWarnings("unchecked")
	public GenericServiceImpl(final Class<?> clazz) {
		String clazzName = clazz.getSimpleName();
		String beanName = clazzName.substring(0, 1).toLowerCase()
				+ clazzName.substring(1, clazzName.length()) + "DaoImpl";
		Object obj = SpringContextHelper.context.getBean(beanName);
		genericDao = (GenericDao<T, PK>) obj;
	}

	public void create(T entity) {
		try {
			Class<?> superClass = entity.getClass().getSuperclass();
			Field creator = superClass.getDeclaredField("creator");
			creator.setAccessible(true);
			creator.set(entity, "罗兰春");
			genericDao.create(entity);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public T read(PK id) {
		return genericDao.read(id);
	}

	public void update(T entity) {
		try {
			Class<?> superClass = entity.getClass().getSuperclass();
			Field editTime = superClass.getDeclaredField("editTime");
			Field editor = superClass.getDeclaredField("editor");
			editTime.setAccessible(true);
			editor.setAccessible(true);
			editTime.set(entity, new Date());
			editor.set(entity, "罗兰春");
			genericDao.update(entity);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void delete(PK id) {
		genericDao.delete(this.read(id));
	}

	public List<T> findAll() {
		return genericDao.findAll();
	}

	public List<T> findAll(QueryItem item) {
		return genericDao.findAll(item);
	}

	public Page<T> findPage(Page<T> page) {
		return genericDao.findPage(page);
	}

	public Page<T> findPage(QueryItem item, Page<T> page) {
		return genericDao.findPage(item, page);
	}

	public Page<T> findPageByQuery(Page<T> page, Class<T> clazz,
			List<ParmItem> parms) {
		QueryItem item = new QueryItem(clazz);
		for (int i = 0; i < parms.size(); i++) {
			ParmItem parm = parms.get(i);
			if (parm == null || parm.getFieldValue() == null) {
				continue;
			}
			if (i == 0) {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getFieldValue());
			} else {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getLogicOperator(), parm.getFieldValue());
			}
		}
		return findPage(item, page);
	}

	public Page<T> findPageByQuery(Page<T> page, Class<T> clazz, ParmItem parm) {
		QueryItem item = new QueryItem(clazz);
		if (parm != null && parm.getFieldValue() != null) {
			item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
					parm.getFieldValue());
		}
		return findPage(item, page);
	}

	public List<T> findAllByQuery(Class<T> clazz, ParmItem parm) {
		QueryItem item = new QueryItem(clazz);
		if (parm != null && parm.getFieldValue() != null) {
			item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
					parm.getFieldValue());
		}
		return findAll(item);
	}

	public List<T> findAllByQuery(Class<T> clazz, List<ParmItem> parms) {
		QueryItem item = new QueryItem(clazz);
		for (int i = 0; i < parms.size(); i++) {
			ParmItem parm = parms.get(i);
			if (parm == null || parm.getFieldValue() == null) {
				continue;
			}
			if (i == 0) {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getFieldValue());
			} else {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getLogicOperator(), parm.getFieldValue());
			}
		}
		return findAll(item);
	}

	public List<T> findAllByQuery(Class<T> clazz, ParmItem parm, OrderItem order) {
		QueryItem item = new QueryItem(clazz);
		if (parm != null && parm.getFieldValue() != null) {
			item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
					parm.getFieldValue());
		}
		if (order != null && order.getFieldName() != null) {
			item.addOrder(order.getFieldName(), order.getOrderOperator());
		}
		return findAll(item);
	}

	public List<T> findAllByQuery(Class<T> clazz, List<ParmItem> parms,
			List<OrderItem> orders) {
		QueryItem item = new QueryItem(clazz);
		for (int i = 0; i < parms.size(); i++) {
			ParmItem parm = parms.get(i);
			if (parm == null || parm.getFieldValue() == null) {
				continue;
			}
			if (i == 0) {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getFieldValue());
			} else {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getLogicOperator(), parm.getFieldValue());
			}
		}
		for (int i = 0; i < orders.size(); i++) {
			OrderItem order = orders.get(i);
			if (order == null || order.getFieldName() == null) {
				continue;
			}
			item.addOrder(order.getFieldName(), order.getOrderOperator());
		}
		return findAll(item);
	}

	public Page<T> findPageByQuery(Page<T> page, Class<T> clazz, ParmItem parm,
			OrderItem order) {
		QueryItem item = new QueryItem(clazz);
		if (parm != null && parm.getFieldValue() != null) {
			item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
					parm.getFieldValue());
		}
		if (order != null && order.getFieldName() != null) {
			item.addOrder(order.getFieldName(), order.getOrderOperator());
		}
		return findPage(item, page);
	}

	public Page<T> findPageByQuery(Page<T> page, Class<T> clazz,
			List<ParmItem> parms, List<OrderItem> orders) {
		QueryItem item = new QueryItem(clazz);
		for (int i = 0; i < parms.size(); i++) {
			ParmItem parm = parms.get(i);
			if (parm == null || parm.getFieldValue() == null) {
				continue;
			}
			if (i == 0) {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getFieldValue());
			} else {
				item.addCondition(parm.getFieldName(), parm.getFieldOperator(),
						parm.getLogicOperator(), parm.getFieldValue());
			}
		}
		for (int i = 0; i < orders.size(); i++) {
			OrderItem order = orders.get(i);
			if (order == null || order.getFieldName() == null) {
				continue;
			}
			item.addOrder(order.getFieldName(), order.getOrderOperator());
		}
		return findPage(item, page);
	}

}
